﻿#region Copyright (c) 2000-2013 Developer Express Inc.
/*
{*******************************************************************}
{                                                                   }
{       Developer Express .NET Component Library                    }
{                                                                   }
{                                                                   }
{       Copyright (c) 2000-2013 Developer Express Inc.              }
{       ALL RIGHTS RESERVED                                         }
{                                                                   }
{   The entire contents of this file is protected by U.S. and       }
{   International Copyright Laws. Unauthorized reproduction,        }
{   reverse-engineering, and distribution of all or any portion of  }
{   the code contained in this file is strictly prohibited and may  }
{   result in severe civil and criminal penalties and will be       }
{   prosecuted to the maximum extent possible under the law.        }
{                                                                   }
{   RESTRICTIONS                                                    }
{                                                                   }
{   THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES           }
{   ARE CONFIDENTIAL AND PROPRIETARY TRADE                          }
{   SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS   }
{   LICENSED TO DISTRIBUTE THE PRODUCT AND ALL ACCOMPANYING .NET    }
{   CONTROLS AS PART OF AN EXECUTABLE PROGRAM ONLY.                 }
{                                                                   }
{   THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED      }
{   FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE        }
{   COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE       }
{   AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT  }
{   AND PERMISSION FROM DEVELOPER EXPRESS INC.                      }
{                                                                   }
{   CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON       }
{   ADDITIONAL RESTRICTIONS.                                        }
{                                                                   }
{*******************************************************************}
*/
#endregion Copyright (c) 2000-2013 Developer Express Inc.

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using UColor.Core.Helpers;
#if DEMO
using DevExpress.Internal;
using DemoLauncher.Shared;
#else
using DevExpress.Utils;
#endif
#if SL
using System.Net;
using System.Threading;
#else
using System.Data;
using System.Data.OleDb;
using System.Deployment.Application;
using System.Windows.Interop;
#endif
//using UColor.Core.DataClasses;
namespace UColor.WPF.Helpers {
	public static class DemoHelper {
		const string SLAndXbapSysString = "#";
		const string CoSysString = "{0}/{1}.application?&";
		static Dictionary<Assembly, CodeLanguage> languages = new Dictionary<Assembly, CodeLanguage>();
		static Dictionary<Assembly, Type> startups = new Dictionary<Assembly, Type>();
		public static string GetSystemString(string platformLink, string clickOnceApplicationName) {
			return EnvironmentHelper.IsSL || EnvironmentHelper.IsXBAP ? SLAndXbapSysString : string.Format(CoSysString, platformLink, clickOnceApplicationName);
		}
		public static Type GetStartup(Assembly demoAssembly) {
			Type appType;
			if(!startups.TryGetValue(demoAssembly, out appType)) {
				appType = GetStartupCore(demoAssembly);
				startups.Add(demoAssembly, appType);
			}
			return appType;
		}
		public static string GetPath(string path, Assembly assembly) {
			return GetDemoLanguage(assembly) == CodeLanguage.VB ? string.Empty : path;
		}
		public static string GetCodeSuffix(Assembly assembly) {
			return GetDemoLanguage(assembly) == CodeLanguage.VB ? ".vb" : ".cs";
		}
		public static CodeLanguage GetDemoLanguage(Assembly assembly) {
			CodeLanguage language;
			if(!languages.TryGetValue(assembly, out language)) {
				language = GetDemoLanguageCore(assembly);
				languages.Add(assembly, language);
			}
			return language;
		}
        //public static XpfPlatformSupport DemoVisibility {
        //    get {
        //        if(EnvironmentHelper.IsSL) return XpfPlatformSupport.Silverlight;
        //        if(EnvironmentHelper.IsXBAP) return XpfPlatformSupport.OnlyXbap;
        //        return XpfPlatformSupport.WpfNoXbap;
        //    }
        //}
		public static string GetCodeText(Assembly demo, string moduleName, CodeLanguage language) {
			return GetText(GetCodeTextStream(demo, moduleName, language));
		}
		public static Stream GetCodeTextStream(Assembly demo, string moduleName, CodeLanguage language) {
			string[] extensions = GetModuleCodeSuffixes(language);
			foreach(string extension in extensions) {
				Stream s = GetModuleTextFromResources(demo, moduleName, extension);
				if(s != null) return s;
			}
			foreach(string extension in extensions) {
				Stream s = GetModuleTextFromFile(demo, moduleName, language, extension);
				if(s != null) return s;
			}
			return null;
		}
		static string[] GetModuleCodeSuffixes(CodeLanguage language) {
			switch(language) {
				case CodeLanguage.CS: return new string[] { ".xaml.cs" };
				case CodeLanguage.VB: return new string[] { ".xaml.vb" };
#if SL
				default: return new string[] { ".SL.xaml", ".xaml" };
#else
				default: return new string[] { ".xaml" };
#endif
			}
		}
		static string GetModuleCodeBaseFolder(CodeLanguage language) {
			return language == CodeLanguage.VB ? "VB" : "CS";
		}
		static string GetText(Stream s) {
			if(s == null) return string.Empty;
			using(StreamReader reader = new StreamReader(s))
				return reader.ReadToEnd();
		}
		static Stream GetModuleTextFromResources(Assembly assembly, string moduleName, string extensionFile) {
			return AssemblyHelper.GetResourceStream(assembly, moduleName + extensionFile, false);
		}
#if SL
		static Stream GetModuleTextFromFile(Assembly demo, string moduleName, CodeLanguage language, string extensionFile) {
			string demoName = AssemblyHelper.GetPartialName(demo);
			byte[] data = DemosMainServiceHelper.GetData("source:" + GetModuleCodeBaseFolder(language) + ":" + demoName + ":" + moduleName + extensionFile);
			return data == null ? null : new MemoryStream(data);
		}
#else
		static Stream GetModuleTextFromFile(Assembly demo, string moduleName, CodeLanguage language, string extensionFile) {
			if(EnvironmentHelper.IsClickOnce) return null;
			string baseFolderName = GetModuleCodeBaseFolder(language);
			Stream s = GetModuleTextFromFileCore(demo, moduleName, language, extensionFile, baseFolderName);
			if(s == null)
				s = GetModuleTextFromFileCore(demo, moduleName, language, extensionFile, Path.Combine("XtraReports", baseFolderName));
			return s;
		}
		static Stream GetModuleTextFromFileCore(Assembly demo, string moduleName, CodeLanguage language, string extensionFile, string baseFolderName) {
			try {
				string baseDir = DataFilesHelper.FindDirectory(baseFolderName);
				string demoName = AssemblyHelper.GetPartialName(demo);
				string[] demoDirs = Directory.GetDirectories(baseDir, demoName + "*", SearchOption.TopDirectoryOnly);
				if(demoDirs.Length == 0) return null;
				string[] files = Directory.GetFiles(demoDirs[0], moduleName + extensionFile, SearchOption.AllDirectories);
				if(files.Length == 0) return null;
				return new FileStream(files[0], FileMode.Open, FileAccess.Read);
			} catch {
				return null;
			}
		}
#endif
		static CodeLanguage GetDemoLanguageCore(Assembly assembly) {
			const string EmbeddedDataName = "EmbeddedData.txt";
			const string EmbeddedDataPath = "Data";
			if(AssemblyHelper.GetEmbeddedResourceStream(assembly, AssemblyHelper.CombineUri(EmbeddedDataPath, EmbeddedDataName), true) != null) return CodeLanguage.CS;
			if(AssemblyHelper.GetEmbeddedResourceStream(assembly, EmbeddedDataName, true) != null) return CodeLanguage.VB;
			throw new Exception("Cannot determine XPF demo code language");
		}
		static Type GetStartupCore(Assembly demoAssembly) {
			Type appType = null;
			Type[] types = demoAssembly.GetExportedTypes();
			foreach(Type type in types) {
				if(type.IsSubclassOf(typeof(StartupBase))) {
					appType = type;
					break;
				}
			}
			return appType;
		}
	}
}
